<?php
/**
 * Created by IntelliJ IDEA. 
 * User: cmn
 * Date: 2019-09-07
 * Time: 11:41
 */

namespace tech\esign_utils;

use tech\esign_constant\Config;

class HttpHelper
{
    public static $connectTimeout = 30;//30 second
    public static $readTimeout = 80;//80 second

    public static function doPost($url,$data,$header=null){
        return self::curl($url,'POST',$data,$header);
    }

    public static function doGet($url,$data,$header){
        return self::curl($url,'GET',$data,$header);
    }

    public static function curl($url, $httpMethod = "GET", $postFields = null,$headers = array())
    {

        if(empty($headers)){
            $headers = array("Content-Type:application/json;charset=UTF-8");
        }
        $headers[] = 'Expect:';
        $logData = array(
            'url'=>$url,
            'httpMethod'=>$httpMethod,
            'data'=>$postFields,
            'header'=>$headers
        );

        self::writeLog('curl data:');
        self::writeLog($logData);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $httpMethod);
        if(Config::$proxyConf['ENABLE_HTTP_PROXY']) {
            curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
            curl_setopt($ch, CURLOPT_PROXY, Config::$proxyConf['HTTP_PROXY_IP'] );
            curl_setopt($ch, CURLOPT_PROXYPORT, Config::$proxyConf['HTTP_PROXY_PORT']);
            curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_FAILONERROR, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

//        curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($postFields) ? self::getPostHttpBody($postFields) : $postFields);

        $postData = is_array($postFields) ? json_encode($postFields) : $postFields;
        curl_setopt($ch, CURLOPT_POSTFIELDS,$postData );

        if (self::$readTimeout) {
            curl_setopt($ch, CURLOPT_TIMEOUT, self::$readTimeout);
        }
        if (self::$connectTimeout) {
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::$connectTimeout);
        }
        //https request
        if(strlen($url) > 5 && strtolower(substr($url,0,5)) == "https" ) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }
        if (is_array($headers) && 0 < count($headers))
        {
            curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
        }
        $curlRes = curl_exec($ch);
        self::writeLog('curl response:');
        self::writeLog($curlRes);

        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if($httpCode != 200){
            throw new \Exception('curl http error:'.$httpCode);
        }
        return $curlRes;
    }

    static function postFile($url, array $keysArr = array())
    {

        // invalid characters for "name" and "filename"
        static $disallow = array("\0", "\"", "\r", "\n");

        $body = array();
        // build normal parameters
        foreach ($keysArr as $k => $v) {
            //var_dump($keysArr);
            if ($k == 'file') {
                $data = self::getFileStream($v->name);
                if(is_array($data)){
                    return $data;
                }
                $srcPath = self::encodePath($v->name);
                $file = '@'.$srcPath;

                $body[] = implode("\r\n", array(
                    "Content-Disposition: form-data; name=\"file\"; filename=\"{$file}\"",
                    "Content-Type: application/octet-stream",
                    "",
                    $data,
                ));
            }

            $k = str_replace($disallow, "_", $k);
            $body[] = implode("\r\n", array(
                "Content-Disposition: form-data; name=\"{$k}\"",
                "",
                filter_var($v),
            ));
        }

        // generate safe boundary
        do {
            $boundary = "---------------------" . md5(mt_rand() . microtime());
        } while (preg_grep("/{$boundary}/", $body));

        // add boundary for each parameters
        array_walk($body, function (&$part) use ($boundary) {
            $part = "--{$boundary}\r\n{$part}";
        });

        // add final boundary
        $body[] = "--{$boundary}--";
        $body[] = "";

//        echo $url;exit;
        $res = self::doPost(
            $url,
            implode("\r\n", $body),
            $header = array(
                "Content-Type: multipart/form-data; boundary={$boundary}",
            )
        );
        return $res;
    }

    static function getFileStream($filePath){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $filePath);
        curl_setopt($curl, CURLOPT_REFERER, '');
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_HEADER, true); // 输出HTTP头 true
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);//SSL证书认证
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);

        $result = curl_exec($curl);
        $httpCode = curl_getinfo($curl,CURLINFO_HTTP_CODE);

        if($httpCode != 200){
            if(isset($httpCodeMap[$httpCode])){
                return array('errCode'=>$httpCode,'msg'=>getCurlErrMap($httpCode));
            }
            $info['errCode'] = $httpCode;
            return $info;
        }
        return $result;
    }

    /**
     * 检查是否是中文编码
     * @param $str
     * @return int
     */
    public static function chkChinese($str)
    {
        return preg_match('/[\x80-\xff]./', $str);
    }

    /**
     * 检测是否windows系统，因为windows系统默认编码为GBK
     * @return bool
     */
    public static function isWin()
    {
        return strtoupper(substr(PHP_OS, 0, 3)) == "WIN";
    }

    /**
     * 主要是由于windows系统编码是gbk，遇到中文时候，如果不进行转换处理会出现找不到文件的问题
     * @param $file_path
     * @return string
     */
    public static function encodePath($file_path)
    {
        if (self::chkChinese($file_path) && self::isWin()) {
            $file_path = iconv('utf-8', 'gbk', $file_path);
        }
        return $file_path;
    }

    static function getPostHttpBody($postFildes){
        $content = "";
        foreach ($postFildes as $apiParamKey => $apiParamValue)
        {
            if(is_string($apiParamValue)){
                $content .= "$apiParamKey=" . urlencode($apiParamValue) . "&";
            }
        }
        return substr($content, 0, -1);
    }
    static function getHttpHearders($headers)
    {
        $httpHeader = array();
        foreach ($headers as $key => $value)
        {
            array_push($httpHeader, $key.":".$value);
        }
        return $httpHeader;
    }

    static function writeLog($text) {
		if (ESIGN_DEBUGE)
		{
			if(is_array($text) || is_object($text)){
				$text = json_encode($text);
			}
			
			file_put_contents(ESIGN_LOG_DIR . "vipfile_esign_" . date('Y-m-d') . ".log", date('Y-m-d H:i:s') . "  " . $text . "\r\n", FILE_APPEND);

		}
    }
}
